package com.fengye.security.validation;

import com.fengye.security.validation.annotation.ValidPassword;
import lombok.RequiredArgsConstructor;
import org.passay.*;
import org.passay.spring.SpringMessageResolver;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.Arrays;

/**
 * @author fengyexjtu@126.com
 * @date 2022年04月13日 2:01 PM
 */

@RequiredArgsConstructor
public class PasswordConstraintValidator implements ConstraintValidator<ValidPassword, String> {
    private final SpringMessageResolver messageResolver;
    @Override
    public void initialize(ValidPassword constraintAnnotation) {}

    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        PasswordValidator passwordValidator = new PasswordValidator(messageResolver, Arrays.asList(
                new LengthRule(5, 20), // 长度
                new CharacterRule(EnglishCharacterData.UpperCase, 1), // 最少一个大写字母
                new CharacterRule(EnglishCharacterData.LowerCase, 1), // 最少一个小写字母
                new CharacterRule(EnglishCharacterData.Special, 1), // 最少一个特殊字符
                new CharacterRule(EnglishCharacterData.Digit, 1), // 最少一个数字
                new IllegalSequenceRule(EnglishSequenceData.Alphabetical, 5, false), // 字母表连续 5 位非法,如 abcdef
                new IllegalSequenceRule(EnglishSequenceData.Numerical, 5, false),// 数字连续 5 位非法,如 12345
                new IllegalSequenceRule(EnglishSequenceData.USQwerty, 5, false), // 键盘连续 5 位,如 qwert
                new WhitespaceRule()
        ));
        RuleResult result = passwordValidator.validate(new PasswordData(value));
        if (result.isValid()) {
            return true;
        }
        // 重新设置返回错误消息的格式,将所有消息合并
        context.disableDefaultConstraintViolation();
        context.buildConstraintViolationWithTemplate(String.join(" ", passwordValidator.getMessages(result)))
                .addConstraintViolation();
        return false;
    }

}
